extends Control

signal timing_changed
signal hour_changed
signal min_changed
signal sec_changed


const HOUR_MAX: int = 12
const MIN_MAX: int = 59
const SEC_MAX: int = 59
const DEFAULT_TIME: int = 0
const BTN_START_TEXT := "开始"
const BTN_STOP_TEXT := "停止"


@export var hour_slider: HSlider
@export var min_slider: HSlider
@export var sec_slider: HSlider

@export var user_hour_text: LineEdit
@export var user_min_text: LineEdit
@export var user_sec_text: LineEdit
@export var time_label: Label
@export var start_btn: Button
@export var timer: Timer

@export var sound_player: AudioStreamPlayer
@export var timeout_sound: AudioStreamPlayer

var user_time: int = DEFAULT_TIME
var time_left: int = DEFAULT_TIME

var timing := false

var user_hour: int = 0
var user_min: int = 0
var user_sec: int = 0

var dragging = false
var mouse_drag_pos := Vector2.ZERO

# Called when the node enters the scene tree for the first time.
func _ready():
	timer.timeout.connect(_on_timer_timeout)
	timing_changed.connect(_on_timing_changed)
	hour_changed.connect(_on_hour_changed)
	min_changed.connect(_on_min_changed)
	sec_changed.connect(_on_sec_changed)
	update_label_text()
	update_time_editor()



func update_user_time():
	user_time = user_hour * 3600 + user_min * 60 + user_sec
	time_left = user_time
	update_label_text()


func turn_user_time_editors():
	user_hour_text.editable = !timing
	user_min_text.editable = !timing
	user_sec_text.editable = !timing
	user_hour_text.selecting_enabled = !timing
	user_min_text.selecting_enabled = !timing
	user_sec_text.selecting_enabled = !timing
	hour_slider.editable = !timing
	min_slider.editable = !timing
	sec_slider.editable = !timing
	


func update_time_editor():
	var hour = time_left / 3600
	var mint = (time_left % 3600) / 60
	var sec = time_left % 60
	var hour_str = str(hour)
	var mint_str = str(mint)
	var sec_str = str(sec)
	user_hour_text.text = hour_str
	user_min_text.text = mint_str
	user_sec_text.text = sec_str
	hour_slider.value = hour
	min_slider.value = mint
	sec_slider.value = sec
	

func update_label_text():
	start_btn.disabled = (time_left <= 0)
	var hour = time_left / 3600
	var mint = (time_left % 3600) / 60
	var sec = time_left % 60
	var hour_str = str(hour)
	var mint_str = str(mint)
	var sec_str = str(sec)
	if hour_str.length() == 1:
		hour_str = "0" + hour_str
	if mint_str.length() == 1:
		mint_str = "0" + mint_str
	if sec_str.length() == 1:
		sec_str = "0" + sec_str
	time_label.text = hour_str + ":" + mint_str + ":" + sec_str


func _on_timer_timeout():
	time_left -= 1
	sound_player.play()
	update_label_text()
	if time_left <= 0:
		timeout_sound.play()
		timing = false
		emit_signal("timing_changed")
		change_time_button_text()


func countdown():
	#print(timer.time_left)
	if timing && time_left > 0 && timer.is_stopped():
		timer.start()
		


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta):
	countdown()


func change_time_button_text():
	if timing:
		start_btn.text = BTN_STOP_TEXT
	else:
		start_btn.text = BTN_START_TEXT
		

func _on_timer_start_button_pressed():
	timing = !timing
	emit_signal("timing_changed")
	if time_left <= 0:
		reset_time()
	change_time_button_text()


func reset_time():
	time_left = user_time
	update_label_text()

## let time left = user time
func _on_reset_button_pressed():
	timing = false
	emit_signal("timing_changed")
	reset_time()
	change_time_button_text()


func _on_timing_changed():
	turn_user_time_editors()
	if not timing and not timer.is_stopped():
		timer.stop()


func _on_hour_changed(value):
	if typeof(value) == TYPE_FLOAT:
		user_hour = int(value)
	if typeof(value) == TYPE_STRING:
		user_hour = clampi(int(value), 0, HOUR_MAX)
		hour_slider.set_value_no_signal(user_hour)
	user_hour_text.text = str(user_hour)
	update_user_time()
	
	
func _on_min_changed(value):
	if typeof(value) == TYPE_FLOAT:
		user_min = int(value)
	if typeof(value) == TYPE_STRING:
		user_min = clampi(int(value), 0, MIN_MAX)
		min_slider.set_value_no_signal(user_min)
	user_min_text.text = str(user_min)
	update_user_time()
	
	
	
func _on_sec_changed(value):
	if typeof(value) == TYPE_FLOAT:
		user_sec = int(value)
	if typeof(value) == TYPE_STRING:
		user_sec = clampi(int(value), 0, SEC_MAX)
		min_slider.set_value_no_signal(user_sec)
	user_sec_text.text = str(user_sec)
	update_user_time()

	
	
	

func _on_hour_line_edit_text_changed(new_text):
	emit_signal("hour_changed", new_text)


func _on_min_line_edit_text_changed(new_text):
	emit_signal("min_changed", new_text)


func _on_sec_line_edit_text_changed(new_text):
	emit_signal("sec_changed", new_text)

func _on_hour_slider_value_changed(value):
	emit_signal("hour_changed", value)


func _on_min_slider_value_changed(value):
	emit_signal("min_changed", value)


func _on_sec_slider_value_changed(value):
	emit_signal("sec_changed", value)


func _unhandled_input(event):
	if event is InputEventMouseButton:
		if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
			dragging = true
			mouse_drag_pos = get_viewport().get_mouse_position()
#			print(mouse_drag_pos)
		else:
			dragging = false
	
	if event is InputEventMouseMotion and dragging:
		var mouse_pos = get_viewport().get_mouse_position()
		get_tree().root.position = Vector2(get_tree().root.position) + mouse_pos - mouse_drag_pos


func _on_quit_button_pressed():
	get_tree().quit(0)
	


func _on_background_alpha_slider_value_changed(value):
	self_modulate.a = value




